package com.yml.mall.handle;

import com.yml.mall.currentexception.MyException;
import com.yml.mall.currentexception.UserLoginException;
import com.yml.mall.enums.ResponseEnum;
import com.yml.mall.vo.ResponseVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.ValidationException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Set;

/**
 * @ClassName ExceptionHandler
 * @Author Administrator
 * @Date 2020/4/7   13:40
 */
//@RestControllerAdvice
@ControllerAdvice
@Slf4j
public class MyExceptionHandler  {
    @ExceptionHandler(MyException.class)
    @ResponseBody
    @ResponseStatus
    public ResponseVO exception(MyException e){
        log.error("MyExceptionHandler",e.getMessage());
        return ResponseVO.error(e.getCode(),e.getMessage());
    }

    @ExceptionHandler(RuntimeException.class)
    @ResponseBody
    @ResponseStatus
    public ResponseVO exception(RuntimeException e){
        log.error("MyExceptionHandler", Objects.requireNonNull(e.getMessage()));
        return ResponseVO.error(ResponseEnum.ERROR.getCode(),Objects.requireNonNull(e.getMessage()));
    }

    @ExceptionHandler(UserLoginException.class)
    @ResponseBody
    public ResponseVO exception(UserLoginException e){
        log.error("MyExceptionHandler",e.getMessage());
        return ResponseVO.error(ResponseEnum.NOT_LOGIN);
    }

    /**
     * 统一异常处理，字段验证
     * @param e
     * @return
     */
    @ExceptionHandler(ValidationException.class)
    @ResponseBody
    @ResponseStatus
    public  ResponseVO exception(ValidationException e){
        List<String> errorMsg = new ArrayList<>();
        if (e instanceof ConstraintViolationException) {
            ConstraintViolationException exs = (ConstraintViolationException) e;

            Set<ConstraintViolation<?>> violations = exs.getConstraintViolations();
            for (ConstraintViolation<?> item : violations) {
                /**打印验证不通过的信息*/
                System.out.println(item.getMessage());
                errorMsg.add(item.getMessage());
            }
        }

        return ResponseVO.error(ResponseEnum.FIELD_ERROR,"ValidationException:"+errorMsg.toString());
    }


    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody
    @ResponseStatus
    public ResponseVO exception(MethodArgumentNotValidException exception) {
        BindingResult result = exception.getBindingResult();
        final List<FieldError> fieldErrors = result.getFieldErrors();
        List<String> errorMsg = new ArrayList<>();
        for (FieldError error : fieldErrors) {
            errorMsg.add(error.getDefaultMessage());
        }
        return ResponseVO.error(ResponseEnum.NOT_LOGIN,"MethodArgumentNotValidException:"+fieldErrors.toString());
    }

    @ExceptionHandler(MissingServletRequestParameterException.class)
    @ResponseBody
    @ResponseStatus
    public ResponseVO exception(MissingServletRequestParameterException e){
        log.error("MyExceptionHandler",e.getMessage());
        return ResponseVO.error(ResponseEnum.FIELD_ERROR.getCode(),"MissingServletRequestParameterException"+Objects.requireNonNull(e.getMessage()));
    }

    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    @ResponseBody
    @ResponseStatus
    public ResponseVO exception(HttpRequestMethodNotSupportedException e){
        log.error("MyExceptionHandler",e.getMessage());
        return ResponseVO.error(ResponseEnum.REQUEST_ERROR.getCode(),"HttpRequestMethodNotSupportedException"+Objects.requireNonNull(e.getMessage()));
    }
}
